package com.trc202.CS350;
//Term Project Ted Chandler and Daniel Moore
import com.trc202.MemoryManagers.MemoryManager;


public class Processor {
	
	Job[] jobs = null;
	MemoryManager memManager = null;
	int lastJobDone = -1;
	
	public Processor(Job[] jobs, MemoryManager memManager){
		this.jobs = jobs;
		this.memManager = memManager;
	}
	
	/**
	 * Request the MemoryManager do its Job bringing Jobs into memory and process the next avalable job
	 */
	public void process(){
		//Manage the memory in the intended way
		memManager.manageMemory();
		//Return job to its previous state as we aren't running it anymore
		if(lastJobDone != -1 && jobs[lastJobDone].getStatus() != Job.Status.FINISHED){
			jobs[lastJobDone].setStatus(Job.Status.READY);
		}
		
		//Look for the next job ready to run
		int nextPlannedJob = (lastJobDone + 1) % jobs.length;
		while(jobs[nextPlannedJob].getStatus() != Job.Status.READY && nextPlannedJob != lastJobDone && getReadyJobsSize(jobs) != 0){
			nextPlannedJob = (nextPlannedJob + 1) % jobs.length;
		}
		if(getReadyJobsSize(jobs) == 0){
		//No jobs are available do nothing
		}else{
			//We are executing next planned job now
			executeJob(jobs[nextPlannedJob]);
			lastJobDone = nextPlannedJob;
		}
	}
	
	/**
	 * Gets the number of jobs which are ready to be executed
	 * @param job array which to search through
	 * @return number of jobs avalable for execution
	 */
	private int getReadyJobsSize(Job[] jobs){
		int readyJobs = 0;
		for(int i = 0; i < jobs.length; i++){
			if(jobs[i].getStatus() == Job.Status.READY){
				readyJobs = readyJobs + 1;
			}
		}
		return readyJobs;
	}
	
	/**
	 * Executes the given Job, will throw a runtime exception if the job is not ready to be executed
	 * @param Job to be executed
	 */
	private void executeJob(Job j){
		if(j.getStatus() != Job.Status.READY){
			throw new RuntimeException("Job is not ready!");
		}else{
			j.setStatus(Job.Status.RUNNING);
			j.decrementRemainingExecutionTime();
		}
	}
}
